package test;

import net.rubyeye.xmemcached.KeyIterator;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.exception.MemcachedException;
import net.rubyeye.xmemcached.utils.AddrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;

import java.util.concurrent.TimeoutException;

public class XMemcachedCache {

	private MemcachedClient client;
	//命名空间
	private String namespace;
	//memcache服务地址
	private String memcacheServer;
	private static final Logger log = LoggerFactory.getLogger(XMemcachedCache.class);
	//缓存有效时间
	private int expire;
	//缓存操作超时时间
	private int timeout;

	public XMemcachedCache() {
	}

	public XMemcachedCache(String namespace,int expire,int timeout, MemcachedClient client, String memcacheServer) {
		if(log.isDebugEnabled())
			log.debug("创建了namespace:{}的缓存",namespace);
		this.namespace = namespace;
		this.client = client;
		this.memcacheServer = memcacheServer;
		this.expire = expire;
		this.timeout = timeout;
	}

	@Autowired
	public void setMemcachedClient(MemcachedClient client){
		Assert.notNull(client,"memcached cache cannot be null!");
		this.client = client;
	}



	//获取
	public <T> T getValue(String key,T defaultValue){
		try {
			if(log.isDebugEnabled())
				log.debug("select key is {},namespace is {}, defaultValue is ",new Object[]{key,namespace,defaultValue});
			if(timeout>0)
				return (T)client.withNamespace(namespace,client1 -> client1.get(key,timeout));
			else
				return (T)client.withNamespace(namespace,client1 -> client1.get(key));
		} catch (TimeoutException e) {
			log.warn("缓存操作超时",e);
		} catch (InterruptedException e) {
			log.warn("memcached连接被中断",e);
		} catch (MemcachedException e) {
			log.warn("memcached异常",e);
		}
		return defaultValue;
	}
	//添加或更新
	public void setValue(String key,Object value){
		try {
			if(timeout>0)
				client.withNamespace(namespace,client1 -> client1.set(key,expire,value,timeout));
			else
				client.withNamespace(namespace,client1 -> client1.set(key,expire,value));
		} catch (TimeoutException e) {
			log.warn("缓存操作超时",e);
		} catch (InterruptedException e) {
			log.warn("memcached连接被中断",e);
		} catch (MemcachedException e) {
			log.warn("memcached异常",e);
		}
	}
	//删除
	public void deleValue(String key){
		try {
			client.withNamespace(namespace,client1 -> client1.delete(key));
		} catch (TimeoutException e) {
			log.warn("缓存操作超时",e);
		} catch (InterruptedException e) {
			log.warn("memcached连接被中断",e);
		} catch (MemcachedException e) {
			log.warn("memcached异常",e);
		}
	}
	//清除命名空间的缓存
	public void deleNameSpaceValue(){
		try {
			client.invalidateNamespace(namespace);
		} catch (TimeoutException e) {
			log.warn("缓存操作超时",e);
		} catch (InterruptedException e) {
			log.warn("memcached连接被中断",e);
		} catch (MemcachedException e) {
			log.warn("memcached异常",e);
		}
	}

	/**
	 * namepace和key拼接方式当key 不建议使用
	 * @param key
	 * @param defaultValue
	 * @param <T>
	 * @return
	 */
	@Deprecated
	public <T> T get(String key,T defaultValue) {
		try {
			return (T)client.get(getKey(namespace,key));
		} catch (TimeoutException e) {
			log.warn("缓存获取超时",e);
		} catch (InterruptedException e) {
			log.warn("memcached连接被中断",e);
		} catch (MemcachedException e) {
			log.warn("memcached异常",e);
		}
		return defaultValue;
	}
	@Deprecated
	public void set(String key,Object value){
		try {
			client.setWithNoReply(getKey(namespace,key),expire,value);
		} catch (InterruptedException e) {
			log.warn("memcached连接被中断",e);
		} catch (MemcachedException e) {
			log.warn("memcached异常",e);
		}
	}
	@Deprecated
	public void delete(String key){
		try {
			client.deleteWithNoReply(getKey(namespace,key));
		} catch (InterruptedException e) {
			log.warn("memcached连接被中断",e);
		} catch (MemcachedException e) {
			log.warn("memcached异常",e);
		}
	}
	//清除所有缓存
	public void clearAll(){
		try {
			client.flushAll();
		} catch (TimeoutException e) {
			log.warn("缓存操作超时",e);
		} catch (InterruptedException e) {
			log.warn("memcached连接被中断",e);
		} catch (MemcachedException e) {
			log.warn("memcached异常",e);
		}
	}

	/**
	 * memcached 1.6.x will remove cachedump stats command,so this
	 *             method will be removed in the future 慎用
	 * @param namespace
	 */
	@Deprecated
	public void deleteNameSpace(String namespace){
		try {
			KeyIterator keyIterator = client.getKeyIterator(AddrUtil.getOneAddress(memcacheServer));
			while (keyIterator.hasNext()){
				String key = keyIterator.next();
				if(key.matches(getKey(namespace,"*"))){
					client.deleteWithNoReply(key);
				}
			}
		} catch (TimeoutException e) {
			log.warn("缓存操作超时",e);
		} catch (InterruptedException e) {
			log.warn("memcached连接被中断",e);
		} catch (MemcachedException e) {
			log.warn("memcached异常",e);
		}
	}

	public String getKey(String namespace,String key){
		return namespace+"_"+key;
	}

}
